{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## 向量空间的基与维数、以及矩阵的秩\n",
    "\n",
    "- 基：如果向量空间中的一组向量满足「互相线性无关，它们张成向量空间 V，则它们是向量空间 V 的一组基。该空间的任意向量都能表达为基向量的线性组合」。\n",
    "- 秩：经过线性变换后空间的维数，即该矩阵的线性无关的列（行）的最大数目。\n",
    "  - 对于任何矩阵A均有：矩阵的秩 rank = 矩阵主元列的数目 = 列空间的维数 dimension = 列空间任一组基的向量数\n",
    "\n",
    "## 向量的范数 norm\n",
    "\n",
    "向量范数是将一个向量映射到一个标量的函数 $f$，它体现了一个向量的大小，可以先简单地理解为向量的长度。\n",
    "\n",
    "向量范数 $f$ 需要满足如下属性：\n",
    "\n",
    "- $f(\\alpha x) = |\\alpha|f(x)$\n",
    "  - 即缩放向量 x，得到的范数也将按 x 的绝对值进行缩放\n",
    "- $f(x + y) \\le f(x) + f(y)$\n",
    "  - 很著名的三角不等式，两个向量的范数（长度）之和，肯定不会比两个向量合并后的范数（长度）小\n",
    "- $f(x) \\ge 0$\n",
    "  - 即范数（长度）不能为负数\n",
    "- 只有当向量的所有元素全为 0 时，向量的范数才为 0\n",
    "\n",
    "实际上向量的长度，或者叫欧几里得距离，只是范数的实现方式之一，它被称作 $L_2$ 范数，公式如下：\n",
    "\n",
    "$$\n",
    "{|| x ||}_2 = \\sqrt{\\sum_{i=1}^{n}x_i^2 }\n",
    "$$\n",
    "\n",
    "$L_2$ 范数是最常用的范数，不过为了计算效率，我们更经常使用 $L_2$ 范数的平方，也就是把公式中的根号给去掉。\n",
    "\n",
    "此外，我们还经常 $L_1$ 范数，与 $L_2$ 范数相比，$L_1$ 范数受异常值的影响较小。它的计算方式如下（就是各元素绝对值之和）：\n",
    "\n",
    "$$\n",
    "{|| x ||}_1 = \\sum_{i=1}^{n}|x_i|\n",
    "$$\n",
    "\n",
    "$L_2$ 范数跟 $L_1$ 范数，都是 $L_p$ 范数的特例，$L_p$ 范数的定义如下：\n",
    "\n",
    "$$\n",
    "{|| x ||}_p = {( \\sum_{i=1}^{n}x_i^p )}^{1/p}\n",
    "$$\n",
    "\n",
    "\n",
    "向量的范数还可以进一步泛化到矩阵，最常用矩阵的 Frobenius 范数，是矩阵元素平方和的平方根。\n",
    "\n",
    "$$\n",
    "{|| X ||}_F = \\sqrt{\\sum_{i=1}^{m} \\sum_{j=1}^{n} x_{ij}^2 }\n",
    "$$\n",
    "\n",
    "Frobenius 范数满足向量范数的所有性质，它就像是矩阵形向量的范数。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "norm_l2=tensor(5.), norm_l1=tensor(7.), matrix_norm=tensor(6.)\n"
     ]
    }
   ],
   "source": [
    "# 使用 pytorch 计算范数\n",
    "import torch\n",
    "\n",
    "# 计算 L_2 范数\n",
    "u = torch.tensor([3.0, -4.0])\n",
    "norm_l2 = torch.norm(u)\n",
    "\n",
    "# 计算 L_1 范数\n",
    "norm_l1 = torch.abs(u).sum()\n",
    "\n",
    "# 计算矩阵的 Frobenius 范数\n",
    "matrix_norm = torch.norm(torch.ones((4, 9)))\n",
    "\n",
    "print(f\"{norm_l2=}, {norm_l1=}, {matrix_norm=}\")\n"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
  },
  "kernelspec": {
   "display_name": "Python 3.9.12 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
